package data

import (
	"bytes"
	"encoding/csv"
	"encoding/json"
	"fmt"
	"os"
)

const (
	dataSource = "./data/heroes.csv"
)

const (
	LaneTop    = "TOP"
	LaneJungle = "JUG"
	LaneMid    = "MID"
	LaneAdc    = "ADC"
	LaneSup    = "SUP"
)

var (
	lane2Heroes = make(map[string][]string, 5)
)

func GetHeroes(lane string) ([]string, error) {
	if heroes, ok := lane2Heroes[lane]; ok {
		return heroes, nil
	}

	filename := getDataSourceFilename(lane)
	data, err := os.ReadFile(fmt.Sprintf("./data/%s", filename))
	if err != nil {
		return nil, err
	}

	heroes := make([]string, 0)
	if err = json.Unmarshal(data, &heroes); err != nil {
		return nil, err
	}

	lane2Heroes[lane] = heroes

	return heroes, nil
}

func GetAllHeroes() ([]string, error) {
	lanes := []string{LaneTop, LaneJungle, LaneMid, LaneAdc, LaneSup}
	heroSet := make(map[string]struct{})
	for _, lane := range lanes {
		heroes, err := GetHeroes(lane)
		if err != nil {
			return nil, err
		}

		for _, hero := range heroes {
			heroSet[hero] = struct{}{}
		}
	}

	heroes := make([]string, 0, len(heroSet))
	for hero := range heroSet {
		heroes = append(heroes, hero)
	}

	return heroes, nil
}

func GetAllHeroesFromCSV() ([]string, error) {
	heroesData, err := os.ReadFile(dataSource)
	if err != nil {
		return nil, err
	}

	csvReader := csv.NewReader(bytes.NewReader(heroesData))
	records, err := csvReader.ReadAll()
	if err != nil {
		return nil, err
	}

	heroes := make([]string, 0, len(records))
	for _, record := range records {
		if record[2] == "1" {
			heroes = append(heroes, record[1])
		}
	}

	return heroes, nil
}

func getDataSourceFilename(lane string) string {
	switch lane {
	case LaneTop:
		return "hero_top.json"
	case LaneJungle:
		return "hero_jungle.json"
	case LaneMid:
		return "hero_mid.json"
	case LaneAdc:
		return "hero_bottom.json"
	case LaneSup:
		return "hero_support.json"
	default:
		return ""
	}
}
